package com.adams.custom.page.core.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanMap;
import org.apache.log4j.Logger;

import com.adams.access.db.bean.DicColumn;
import com.adams.core.exception.BusinessException;
import com.adams.custom.page.core.dto.DicColumnDto;
import com.adams.custom.page.core.service.DataService;
import com.adams.custom.page.core.service.DicTableService;
import com.adams.custom.page.core.service.SQLConstructServie;
import com.adams.custom.page.util.ViewConstant;
import com.adams.custom.page.util.ViewUtil;

/**
 * 
 * File Name : DataServiceImpl.java
 * 
 * @Description : <Detail Description for Class >
 * @author 904370 张汉辉
 */
public class DataServiceImpl implements DataService
{
	Logger logger = Logger.getLogger(DataServiceImpl.class.getName());
	/**
	 * Description : 表定义服务类 Author : 904370
	 */
	private DicTableService dicTableService;

	/**
	 * Description : sql组装服务类 Author : 904370
	 */
	private SQLConstructServie SQLConstructServie;

	public void setDicTableService(DicTableService dicTableService)
	{
		this.dicTableService = dicTableService;
	}

	public void setSQLConstructServie(SQLConstructServie SQLConstructServie)
	{
		this.SQLConstructServie = SQLConstructServie;
	}

	@SuppressWarnings("unchecked")
	public List<Map> getDatas(String tablecode, List<String> targetColumncodes,
			LinkedHashMap<String, Map<String, String[]>> conditionColumncodes,
			LinkedHashMap<String, String> orderColumncodes)
			throws BusinessException
	{
		return getDatas(tablecode, targetColumncodes, conditionColumncodes,
				orderColumncodes, 0, 0);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.adams.custom.page.core.service.DataService#getDatas(java.lang
	 * .String, java.util.List, java.util.Map, java.util.Map, java.util.Map)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<Map> getDatas(String tablecode, List<String> targetColumncodes,
			LinkedHashMap<String, Map<String, String[]>> conditionColumncodes,
			LinkedHashMap<String, String> orderColumncodes, int start, int limit)
			throws BusinessException
	{
		logger.info("getDatas method run begin.");
		// TODO Auto-generated method stub

		List<DicColumnDto> dicColumnDtos = new ArrayList<DicColumnDto>();
		DicColumnDto dicColumnDto = null;
		for (String targetColumncode : targetColumncodes)
		{
			String columncode = targetColumncode;
			int pos = targetColumncode.indexOf(ViewConstant.COLUMN_SEQ);
			if (pos > -1)
			{
				columncode = targetColumncode.substring(0, pos);
			}
			DicColumn dicColumn = dicTableService.getDicColumn(tablecode,
					columncode);
			dicColumnDto = new DicColumnDto(dicColumn);
			dicColumnDtos.add(dicColumnDto);

			if (pos > -1)
			{
				List<String> columncodes = ViewUtil.getListBySeq(
						targetColumncode, ViewConstant.COLUMN_SEQ);
				// 判断使用到的表是否在同一个数据库下
				// 如果使用到跨数据库的情况下,不加入查询字段列表中
				if (!dicTableService.isSameDatabase(tablecode, columncodes))
				{
					continue;
				}
				// 如果不跨数据库的情况下,加入查询字段列表中
				DicColumn finalDicColumn = dicTableService.getFinalDicColumn(
						tablecode, columncodes);
				String attributecode = getAttributecode(columncodes,
						finalDicColumn);
				if (!attributecode.equals(finalDicColumn.getDicColumnPK()
						.getColumncode()))
				{
					dicColumnDto = new DicColumnDto(attributecode,
							finalDicColumn);
					dicColumnDtos.add(dicColumnDto);
				}
			}

		}
		String sql = SQLConstructServie.ConstructSearchSQL(tablecode,
				targetColumncodes, conditionColumncodes, orderColumncodes);

		List<Map> dataList = dicTableService.findData(tablecode, dicColumnDtos,
				sql, start, limit);
		List<Map> newDatasList = new ArrayList<Map>();
		if (null != dataList && dataList.size() > 0)
		{

			// 提高性能,方法内缓存
			Map cacheMap = new HashMap();
			for (int i = 0; i < dataList.size(); i++)
			{
				Object object = dataList.get(i);
				Map record = new HashMap();
				Map beanMap = null;
				if (object instanceof Map)
				{
					beanMap = (Map) object;
				} else
				{
					beanMap = new BeanMap(object);
				}

				for (String targetColumncode : targetColumncodes)
				{
					int pos = targetColumncode.indexOf(",");
					String firstColumncode = targetColumncode;
					if (pos > -1)
					{
						firstColumncode = targetColumncode.substring(0, pos);
					}

					if (pos > -1)
					{
						// 要显示的值为关系表的数值

						// 下面处理分为两种情况，
						// 1、在查询结果中包含要显示的值，直接转换显示
						String name = targetColumncode;
						List<String> columncodes = ViewUtil.getListBySeq(name,
								ViewConstant.COLUMN_SEQ);
						DicColumn finalDicColumn = dicTableService
								.getFinalDicColumn(tablecode, columncodes);
						String attributecode = name.replaceAll(
								ViewConstant.COLUMN_SEQ,
								ViewConstant.REPLACE_COLUMN_SEQ);
						boolean needGetEnumerateValue = false;
						String lastColumncode = columncodes.get(columncodes
								.size() - 1);
						String finalColumncode = finalDicColumn
								.getDicColumnPK().getColumncode();
						if (finalDicColumn.getEnumerate().size() > 0
								&& !lastColumncode.equals(finalColumncode))
						{
							attributecode = getAttributecode(columncodes,
									finalDicColumn);
							needGetEnumerateValue = true;
						}
						Object value = null;

						if (beanMap.containsKey(attributecode))
						{
							if (null != beanMap.get(attributecode))
							{
								String beanValue = beanMap.get(attributecode)
										.toString();
								if (needGetEnumerateValue)
								{
									value = finalDicColumn
											.getEnumerateValue(beanValue);
								} else
								{
									value = beanValue;
								}
							} else
							{
								value = "";
							}
						} else
						{
							// 2、不包含时，查询数据库得到结构后显示
							String beanValue = "";
							if (null != beanMap.get(firstColumncode))
							{
								beanValue = beanMap.get(firstColumncode)
										.toString();
							}
							String cacheKey = name + "=" + beanValue;

							if (cacheMap.containsKey(cacheKey))
							{
								value = cacheMap.get(cacheKey);
							} else
							{
								value = dicTableService
										.findValueByTableCodeAndColumncodes(
												tablecode, columncodes, beanMap);
								cacheMap.put(cacheKey, value);
							}
						}
						record.put(name, value);
					} else
					{
						// 要显示的值为本表的数值
						if (null != beanMap.get(firstColumncode))
						{
							record.put(firstColumncode, beanMap.get(
									firstColumncode).toString());
						} else
						{
							record.put(firstColumncode, "");
						}

					}
				}
				newDatasList.add(record);
			}
		}
		logger.info("getDatas method run end.");
		return newDatasList;
	}

	private String getAttributecode(List<String> columncodes,
			DicColumn finalDicColumn) throws BusinessException
	{

		String finalColumncode = finalDicColumn.getDicColumnPK()
				.getColumncode();
		int len = columncodes.size();
		int pos = 0;
		for (int i = len - 1; i > 0; i--)
		{
			String columncode = columncodes.get(i);
			if (columncode.equals(finalColumncode))
			{
				pos = i;
				break;
			}
		}
		StringBuilder attributecodeSB = new StringBuilder();
		for (int i = 0; i < pos; i++)
		{
			String columncode = columncodes.get(i);
			attributecodeSB.append(columncode);
			attributecodeSB.append(ViewConstant.REPLACE_COLUMN_SEQ);
		}
		attributecodeSB.append(finalColumncode);
		return attributecodeSB.toString();
	}
}
